package com.juzhencms.apps.busi.service;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.juzhencms.apps.base.busi.entity.BasicLoginUser;
import com.juzhencms.apps.base.busi.service.MobileMsgService;
import com.juzhencms.apps.base.busi.service.WeixinApiService;
import com.juzhencms.apps.base.common.config.Config;
import com.juzhencms.apps.base.common.database.DBTable;
import com.juzhencms.apps.base.common.util.HtmlUtil;
import com.juzhencms.apps.base.common.util.ObjectUtil;
import com.juzhencms.apps.base.common.util.StringUtil;
import com.juzhencms.apps.busi.entity.AdminLoginUser;
import com.juzhencms.apps.busi.web.DataHistoryController;
import com.juzhencms.apps.common.tread.TreadTasks;

import lombok.extern.slf4j.Slf4j;


@Service
@Slf4j
public class DataHistoryService extends CommonService{

	@Autowired
	private UserService userService;
	
	@Autowired
	private MobileMsgService mobileMsgService;
	
	@Autowired
	private WeixinApiService weixinApiService;
	
	
	@Autowired
	private DictionaryService dictionaryService;
	
	@Autowired
	private TreadTasks treadTasks;
	
	
	/**
	 * 保存数据并触发审批
	 * @param table
	 * @param data
	 * @param moduleName 模块名称，和权限菜单中的模块名需要保持一致，程序中会进行权限判断
	 * @return
	 */
	public int saveCheckData(String table,Map data,String moduleName) {
		//log.info("数据版本信息");
		//log.info(JSON.toJSONString(data));
		
		//判断是否是更新操作
		boolean isUpdate =false;
		//旧数据的审核状态，仅在更新操作中用到这个变量
		int oldDataCheckStatus=1;
		if(data.get("id")!=null) {
			isUpdate =true;
			Map oldData=this.getJdbcDao().queryRow("select id,check_status from "+table+" where id=?", new Object[] {data.get("id")});
			if(oldData!=null) {
				oldDataCheckStatus=Integer.parseInt(oldData.get("check_status").toString());
			}else {
				return 0;
			}
		}
		
		
		Date now=new Date();
		BasicLoginUser loginUser=userService.getLoginUser();
		//获取当前管理员用户的角色
		AdminLoginUser adminLoginUser=null;
		if(loginUser.getType()==1) {
			adminLoginUser=(AdminLoginUser)loginUser;
		}
		
		//查找此数据之前有没有未完成的审批，设置为作废状态
		if(isUpdate) {
			this.getJdbcDao().updateSql("update "+DBTable.checkRecord+" set check_status=3,submit_time=? where data_type=? and data_id=? and check_status=0", new Object[] {now,table,data.get("id")});
		}
		
		
		//判断是否需要审批
		int checkStatus=1;//定义审核状态，默认为审核通过（不需要审核），后面根据此变量的值判定是否需要审批
		Map checkRule=null;//定义审批规则变量
		//Map checkRuleItem=null;//定义审批规则节点变量,已作废，改为支持多个审批节点并行的情况
		List checkRuleItems=new ArrayList();
		//Map menu=null;
		
		
		///修改不再使用menu_id ,使用分类ID
		/*if(data.get("menu_id")!=null) {
			//查询栏目及对应的审批规则
			menu=this.getJdbcDao().queryRow("select id,name,site_id,check_rule_id from "+DBTable.menu+" where id=? and del_flag=0 ", new Object[] {data.get("menu_id")});
			if(menu!=null) {
				int checkRuleId=Integer.parseInt(menu.get("check_rule_id").toString());
				if(checkRuleId>0) {
					checkRule=this.getJdbcDao().queryRow("select * from "+DBTable.checkRule+" where id=? and publish=1 and del_flag=0", new Object[] {checkRuleId});
					if(checkRule!=null) {
						
						//倒序查找审批规则，以便在当前用户符合某个审批角色时直接跳过前面的审批节点
						List checkRuleItemList=this.getJdbcDao().querySql("select * from "+DBTable.checkRuleItem+" where check_rule_id=? and publish=1 and del_flag=0 order by position desc limit 0,100", new Object[] {checkRule.get("id")});
						
						if(checkRuleItemList!=null && checkRuleItemList.size()>0) {
							
							for(int i=0;i<checkRuleItemList.size();i++) {
								Map tmpCheckRuleItem=(Map)checkRuleItemList.get(i);
								
								int checkRuleItemRoleId=(int)tmpCheckRuleItem.get("role_id");
								//如果当前用户拥有此节点的审批角色，则不再继续查找，以后一个节点作为审批的开始节点
								if(adminLoginUser!=null && adminLoginUser.getRoleIdList().contains(checkRuleItemRoleId)) {
									break;
								}
								
								log.info("选择审批节点"+JSON.toJSONString(tmpCheckRuleItem));
								
								
								checkRuleItem=tmpCheckRuleItem;
								checkStatus=0;
							}	
						}	
					}
				}
			}
		}*/
		int checkRuleId=0;
		
		//优先使用数据中的部门属性
		if(data.get("org_id")!=null && !data.get("org_id").toString().equals("")) {
			Map defaultCheckRule=this.getJdbcDao().queryRow("select id from "+DBTable.checkRule+" where org_id=? and publish=1 and del_flag=0 order by position asc,create_time desc,id desc limit 0,1", new Object[] {data.get("org_id")});
			if(defaultCheckRule!=null) {
				checkRuleId=Integer.parseInt(defaultCheckRule.get("id").toString());
			}
		}
		//其次使用提交人的部门属性
		if(checkRuleId==0 && adminLoginUser!=null) {
			Map defaultCheckRule=this.getJdbcDao().queryRow("select id from "+DBTable.checkRule+" where org_id=? and publish=1 and del_flag=0 order by position asc,create_time desc,id desc limit 0,1", new Object[] {adminLoginUser.getOrgId()});
			if(defaultCheckRule!=null) {
				checkRuleId=Integer.parseInt(defaultCheckRule.get("id").toString());
			}
		}
		
		
		//如果部门未设置审批规则，则使用配置的默认审批规则
		if(checkRuleId==0) {
			if(table.equals(DBTable.news) && data.get("category_id")!=null) {
				//查询栏目及对应的审批规则
				Map newsCategory=this.getJdbcDao().queryRow("select id,name,check_rule_id from "+DBTable.newsCategory+" where id=? and del_flag=0 ", new Object[] {data.get("category_id")});
				if(newsCategory!=null) {
					checkRuleId=Integer.parseInt(newsCategory.get("check_rule_id").toString());
					
				}
			}else if(table.equals(DBTable.appResource) && data.get("category_id")!=null) {
				//查询栏目及对应的审批规则
				Map appResourceCategory=this.getJdbcDao().queryRow("select id,name,check_rule_id from "+DBTable.appResourceCategory+" where id=? and del_flag=0 ", new Object[] {data.get("category_id")});
				if(appResourceCategory!=null) {
					checkRuleId=Integer.parseInt(appResourceCategory.get("check_rule_id").toString());
				}
			}
		}
		
		
		//log.info("checkRuleId:"+checkRuleId);
		
		/*if(checkRuleId>0) {
			checkRule=this.getJdbcDao().queryRow("select * from "+DBTable.checkRule+" where id=? and publish=1 and del_flag=0", new Object[] {checkRuleId});
			if(checkRule!=null) {
				
				//倒序查找审批规则，以便在当前用户符合某个审批角色时直接跳过前面的审批节点
				List checkRuleItemList=this.getJdbcDao().querySql("select * from "+DBTable.checkRuleItem+" where check_rule_id=? and publish=1 and del_flag=0 order by position desc limit 0,100", new Object[] {checkRule.get("id")});
				
				if(checkRuleItemList!=null && checkRuleItemList.size()>0) {
					
					for(int i=0;i<checkRuleItemList.size();i++) {
						Map tmpCheckRuleItem=(Map)checkRuleItemList.get(i);
						
						int checkRuleItemRoleId=(int)tmpCheckRuleItem.get("role_id");
						//如果当前用户拥有此节点的审批角色，则不再继续查找，以后一个节点作为审批的开始节点
						if(adminLoginUser!=null && adminLoginUser.getRoleIdList().contains(checkRuleItemRoleId)) {
							break;
						}
						log.info("选择审批节点"+JSON.toJSONString(tmpCheckRuleItem));								
						
						checkRuleItem=tmpCheckRuleItem;
						checkStatus=0;
					}	
				}	
			}
		}*/
		//改进的方法，允许出现自己发自己审核的情况，并且支持并行生成多个批注型的审批
		if(checkRuleId>0) {
			checkRule=this.getJdbcDao().queryRow("select * from "+DBTable.checkRule+" where id=? and publish=1 and del_flag=0", new Object[] {checkRuleId});
			if(checkRule!=null) {
				checkRuleItems=this.getNextCheckRuleItems(checkRuleId, null);
				if(checkRuleItems.size()>0) {
					checkStatus=0;
				}
			}
		}
		
		//保存数据
		if(!isUpdate) {//新增操作
			
			data.put("create_user", loginUser.getId());
			//设置审核状态
			data.put("check_status", checkStatus);
			//int id=this.getJdbcDao().addObj(table, data);
			//调用统一封装的数据保存方法
			int id=this.saveSourceData(table, data);
			data.put("id", id);
			
		}else {//修改操作
			//仅在不需要审核或之前数据审核未通过的情况下保存数据
			if(checkStatus==1 || oldDataCheckStatus!=1) {
				//设置审核状态
				data.put("check_status", checkStatus);
				//this.getJdbcDao().updateObj(table, data, "id");
				//调用统一封装的数据保存方法
				this.saveSourceData(table, data);
			}
		}
		
		
		//保存数据版本信息
		Map historyRecord=new HashMap();
		historyRecord.put("data_type", table);
		historyRecord.put("module_name", moduleName);
		
		
		
		historyRecord.put("menu_id", data.get("menu_id"));
		historyRecord.put("check_status", checkStatus);//设置审核状态
		
		historyRecord.put("create_time",now );
		
		
		if(loginUser!=null) {
			historyRecord.put("user_type", loginUser.getType());
			historyRecord.put("user_id", loginUser.getId());
			historyRecord.put("user_account",loginUser.getUser() );
			historyRecord.put("user_name", loginUser.getName());
		}
		
		historyRecord.put("data_id", data.get("id"));
		historyRecord.put("update_description", data.get("update_description"));
		if(table.equals(DBTable.news)) {
			historyRecord.put("title", data.get("name"));
			
			//去掉不保存至版本表的字段,否则审批通过后会覆盖主表的发布状态、排序、推荐等字段，造成审批前后状态不一致
			data.remove("publish");
			data.remove("recommend");
			data.remove("position");
			
			
		}else if(table.equals(DBTable.appResource)){
			historyRecord.put("title", data.get("name"));
			
			//去掉不保存至版本表的字段,否则审批通过后会覆盖主表的发布状态、排序、推荐等字段，造成审批前后状态不一致
			data.remove("publish");
			data.remove("position");
		}else if(table.equals(DBTable.article)){
			/*if(menu!=null) {
				historyRecord.put("title", menu.get("name"));
			}*/
		}else {
			historyRecord.put("title", data.get("name"));
		}
		
		//如果标题字数过多，则进行截取
		if(historyRecord.get("title")!=null && historyRecord.get("title").toString().length()>100) {
			historyRecord.put("title", historyRecord.get("title").toString().substring(0, 100));
		}
		
		
		historyRecord.put("params", JSON.toJSONString(data));
		int historyId=this.getJdbcDao().addObj(DBTable.dataHistory, historyRecord);
		
		//保存版本后的操作
		if(table.equals(DBTable.appResource)) {//如果是保存素材
			//如果当前版本审核通过，则将之前版本的图片设置为失效
			if(historyRecord.get("check_status").toString().equals("1")) {
				this.getJdbcDao().updateSql("update "+DBTable.file+" set useable=0 where data_type=? and data_id=? and useable=1", new Object[] {table,historyRecord.get("data_id")});
			}
			
			
			//提取正文图片
			String html=data.get("content").toString();
    		
			Set<String> imgs=HtmlUtil.getImgStr(html);
			
			//为了避免重复保存图片，这里用map做重复验证
			Map<String,String> imgsMap=new HashMap<String,String>();
			for(String imgUrl:imgs) {
				if(imgUrl.length()>250) {
					continue;
				}
				
				if(imgsMap.get(imgUrl)!=null) {
					continue;
				}
				
				Map fileRecord=new HashMap();
				fileRecord.put("data_type", historyRecord.get("data_type"));
				fileRecord.put("data_id", historyRecord.get("data_id"));
				fileRecord.put("data_history_id", historyId);
				fileRecord.put("check_status", historyRecord.get("check_status"));
				if(fileRecord.get("check_status").toString().equals("1")) {
					fileRecord.put("useable", 1);
				}else {
					fileRecord.put("useable", 0);
				}
				fileRecord.put("url", imgUrl);
				fileRecord.put("create_time", now);
				this.getJdbcDao().addObj(DBTable.file, fileRecord);
				
				imgsMap.put(imgUrl,"1");
			}
			
			
			
		}else if(table.equals(DBTable.news)) {//如果是保存文章
			//提取正文图片
			String html=data.get("content").toString();
			
			Set<String> imgs=HtmlUtil.getImgStr(html);
			
			//为了避免重复保存图片，这里用map做重复验证
			Map<String,String> imgsMap=new HashMap<String,String>();
			for(String imgUrl:imgs) {
				if(imgUrl.length()>250) {
					continue;
				}
				imgsMap.put(imgUrl, "0");
			}
			
			//查询这些图片中的可用模板素材文件
			if(imgsMap.size()>0) {
				List params=new ArrayList();
				List paramsSqlList=new ArrayList();
				for(String key : imgsMap.keySet()) {  	  
					params.add(key);
					paramsSqlList.add("?");
				}
				
				List resourceImgs=this.getJdbcDao().querySql("select url from "+DBTable.file+" where data_type='app_resource' and useable=1 and url in("+org.apache.commons.lang3.StringUtils.join(paramsSqlList, ",")+")", params.toArray());
				
				
				if(resourceImgs!=null && resourceImgs.size()>0) {
					for(int i=0;i<resourceImgs.size();i++) {
						Map row=(Map)resourceImgs.get(i);
						imgsMap.put(row.get("url").toString(), "1");
					}
				}
				
				
				
				Map externalParamsMap=new HashMap();
				List uncheckImgs=new ArrayList();
				
				//如果匹配到可用素材，设置为审核通过，否则设置为审核不通过
				for(String key : imgsMap.keySet()) {  	  
					int checkStatusValue=Integer.parseInt(imgsMap.get(key));
					
					if(checkStatusValue!=1) {
						uncheckImgs.add(key);
					}
				}
				
				if(uncheckImgs.size()>0) {
					externalParamsMap.put("uncheckImgs", uncheckImgs);
					Map record=new HashMap();
					record.put("id", historyId);
					record.put("external_params", JSON.toJSONString(externalParamsMap));
					this.getJdbcDao().updateObj(DBTable.dataHistory, record, "id");
				}
				
				
			}
		}
		
		//如果需要审批则增加审批记录
		if(checkStatus==0) {
			
			for(int i=0;i<checkRuleItems.size();i++) {
				Map checkRuleItem=(Map)checkRuleItems.get(i);
				//增加审批申请
				Map checkRecord=new HashMap();
				checkRecord.put("check_rule_id", checkRule.get("id"));
				checkRecord.put("check_rule_name", checkRule.get("name"));
				checkRecord.put("check_rule_item_id", checkRuleItem.get("id"));
				checkRecord.put("check_rule_item_asyn", checkRuleItem.get("asyn"));
				checkRecord.put("check_org_id", checkRuleItem.get("org_id"));
				checkRecord.put("check_org_name", checkRuleItem.get("org_name"));
				checkRecord.put("check_role_id", checkRuleItem.get("role_id"));
				checkRecord.put("check_role_name", checkRuleItem.get("role_name"));
				checkRecord.put("data_type", historyRecord.get("data_type"));
				checkRecord.put("data_id", historyRecord.get("data_id"));
				checkRecord.put("data_title", historyRecord.get("title"));
				checkRecord.put("data_history_id", historyId);
				//checkRecord.put("submit_site_id", menu.get("site_id"));
				
				/*Map site=this.getJdbcDao().queryRow("select name from "+DBTable.site+" where id=?", new Object[] {menu.get("site_id")});
				if(site!=null) {
					checkRecord.put("submit_site_name", site.get("name"));
				}*/
				//checkRecord.put("submit_menu_id", menu.get("id"));
				//checkRecord.put("submit_menu_name", menu.get("name"));
				checkRecord.put("submit_user_id", loginUser.getId());
				checkRecord.put("submit_user_name", loginUser.getName());
				if(adminLoginUser!=null) {
					checkRecord.put("submit_org_id", adminLoginUser.getOrgId());
					checkRecord.put("submit_org_name", adminLoginUser.getOrgName());
				}
				checkRecord.put("submit_description", "");
				checkRecord.put("submit_time", now);
				checkRecord.put("create_time", now);

				//this.getJdbcDao().addObj(DBTable.checkRecord, checkRecord);
				//统一的保存审批方法，用于发送通知等
				this.saveCheckRecord(checkRecord);
			}

			
		}
		
		//如何判定是否是新增操作，不管审核状态如何，新增时都要保存保本号到数据表
		
		
		//新增状态或审核通过或旧版本审核未通过情况下更新版本号到数据表
		if(!isUpdate || checkStatus==1 || oldDataCheckStatus!=1) {
			Map updateParam=new HashMap();
			updateParam.put("id", data.get("id"));
			updateParam.put("data_history_id", historyId);
			this.getJdbcDao().updateObj(table, updateParam, "id");
		}
		
		//更新图文微信文章素材
		if(isUpdate && checkStatus==1 && table.equals(DBTable.news)) {
			this.treadTasks.startUpdateWeixinNewsSource(new Integer(data.get("id")+""), false);
		}
		return Integer.parseInt(data.get("id").toString());
		
		
	}
	
	
	

	/*public void updateCheckData(String table,Map data) {
		Date now=new Date();
		Map historyRecord=new HashMap();
		historyRecord.put("data_type", table);
		historyRecord.put("check_status", 1);//版本表默认为审批已经通过
		historyRecord.put("params", JSON.toJSONString(data));
		historyRecord.put("create_time",now );
		
		BasicLoginUser loginUser=userService.getLoginUser();
		if(loginUser!=null) {
			historyRecord.put("user_type", loginUser.getType());
			historyRecord.put("user_id", loginUser.getId());
			historyRecord.put("user_account",loginUser.getUser() );
			historyRecord.put("user_name", loginUser.getName());
		}
		
		historyRecord.put("data_id", data.get("id"));
		historyRecord.put("menu_id", data.get("menu_id"));
		if(table.equals(DBTable.news)) {
			
			historyRecord.put("title", data.get("name"));
		}else if(table.equals(DBTable.article)){
			
			if(data.get("menu_id")!=null) {
				//查询栏目
				Map menu=this.getJdbcDao().queryRow("select id,name,site_id,check_rule_id from "+DBTable.menu+" where id=? and del_flag=0 ", new Object[] {data.get("menu_id")});
				historyRecord.put("title", menu.get("name"));
			}
			
		}else {
			
			historyRecord.put("title", data.get("name"));
		}
		
		if(historyRecord.get("title")!=null && historyRecord.get("title").toString().length()>100) {
			historyRecord.put("title", historyRecord.get("title").toString().substring(0, 100));
		}
		
		int historyId=this.getJdbcDao().addObj(DBTable.dataHistory, historyRecord);
		
		//审批部分处理开始
		//查找此数据之前有没有未完成的审批，设置为作废状态
		this.getJdbcDao().updateSql("update "+DBTable.checkRecord+" set check_status=3,submit_time=? where data_type=? and data_id=? and check_status=0", new Object[] {now,historyRecord.get("data_type"),historyRecord.get("data_id")});
		
		//默认为不需要审批
		int checkStatus=1;
		
		if(data.get("menu_id")!=null) {
			//查询栏目及对应的审批规则
			Map menu=this.getJdbcDao().queryRow("select id,name,site_id,check_rule_id from "+DBTable.menu+" where id=? and del_flag=0 ", new Object[] {data.get("menu_id")});
			if(menu!=null) {
				int checkRuleId=Integer.parseInt(menu.get("check_rule_id").toString());
				if(checkRuleId>0) {
					Map checkRule=this.getJdbcDao().queryRow("select * from "+DBTable.checkRule+" where id=? and publish=1 and del_flag=0", new Object[] {checkRuleId});
					if(checkRule!=null) {
						List checkRuleItemList=this.getJdbcDao().querySql("select * from "+DBTable.checkRuleItem+" where check_rule_id=? and publish=1 and del_flag=0 order by position desc limit 0,100", new Object[] {checkRule.get("id")});
						
						if(checkRuleItemList!=null && checkRuleItemList.size()>0) {
							//获取当前管理员用户的角色
							AdminLoginUser adminLoginUser=null;
							if(loginUser.getType()==1) {
								adminLoginUser=(AdminLoginUser)loginUser;
							}
							
							Map checkRuleItem=null;
							
							for(int i=checkRuleItemList.size()-1;i>=0;i--) {
								Map tmpCheckRuleItem=(Map)checkRuleItemList.get(i);
								
								int checkRuleItemRoleId=(int)tmpCheckRuleItem.get("role_id");
								//如果当前用户拥有此节点的审批角色，则不再继续查找，以后一个节点作为审批的开始节点
								if(adminLoginUser!=null && adminLoginUser.getRoleIdList().contains(checkRuleItemRoleId)) {
									break;
								}
								checkRuleItem=tmpCheckRuleItem;
							}
							
							//确定当前开始的审批节点
							if(checkRuleItem!=null) {
								checkStatus=0;
								
								//增加审批申请
								Map checkRecord=new HashMap();
								checkRecord.put("check_rule_id", checkRule.get("id"));
								checkRecord.put("check_rule_name", checkRule.get("name"));
								checkRecord.put("check_rule_item_id", checkRuleItem.get("id"));
								checkRecord.put("check_role_id", checkRuleItem.get("role_id"));
								checkRecord.put("check_role_name", checkRuleItem.get("role_name"));
								checkRecord.put("data_type", historyRecord.get("data_type"));
								checkRecord.put("data_id", historyRecord.get("data_id"));
								checkRecord.put("data_title", historyRecord.get("title"));
								checkRecord.put("data_history_id", historyId);
								checkRecord.put("submit_site_id", menu.get("site_id"));
								
								Map site=this.getJdbcDao().queryRow("select name from "+DBTable.site+" where id=?", new Object[] {menu.get("site_id")});
								if(site!=null) {
									checkRecord.put("submit_site_name", site.get("name"));
								}
								checkRecord.put("submit_menu_id", menu.get("id"));
								checkRecord.put("submit_menu_name", menu.get("name"));
								checkRecord.put("submit_user_id", loginUser.getId());
								checkRecord.put("submit_user_name", loginUser.getName());
								if(adminLoginUser!=null) {
									checkRecord.put("submit_org_id", adminLoginUser.getOrgId());
									checkRecord.put("submit_org_name", adminLoginUser.getOrgName());
								}
								checkRecord.put("submit_description", "");
								checkRecord.put("submit_time", now);
								checkRecord.put("create_time", now);

								this.getJdbcDao().addObj(DBTable.checkRecord, checkRecord);
							}
						}	
					}
				}
			}
		}
		//如果当前版本需要审批，把审批状态也更新到版本表
		if(checkStatus==0) {
			this.getJdbcDao().updateSql("update "+DBTable.dataHistory+" set check_status=? where id=?", new Object[] {checkStatus,historyId});
		}
		
		
		
		
		if(checkStatus==1) {
			//将审批状态和版本号更新到数据表
			Map updateParam=new HashMap();
			updateParam.put("id", historyRecord.get("data_id"));
			updateParam.put("check_status", checkStatus);
			updateParam.put("data_history_id", historyId);
			this.getJdbcDao().updateObj(table, updateParam, "id");
		}
		

		
	}*/
	/**
	 * 获取最新的有效版本（不包含作废的版本）
	 * @param table
	 * @param id
	 * @return
	 */
	public Map getLastValidVersion(String table,int id) {
		if(id==0) {
			return null;
		}
		Map version= this.getJdbcDao().queryRow("select * from "+DBTable.dataHistory+" where data_type=? and data_id=? and check_status!=3 order by create_time desc,id desc limit 0,1 ", new Object[] {table,id});
		if(version==null){
			//如果没有符合的版本，则查询最后一个，即便是已作废状态也显示出来
			version= this.getJdbcDao().queryRow("select * from "+DBTable.dataHistory+" where data_type=? and data_id=? order by create_time desc,id desc limit 0,1 ", new Object[] {table,id});
		}
		
		if(version!=null) {
			dictionaryService.setDictionaryText(version, "check_status", dictionaryService.getDictionaryItemList("checkStatusVars"));
			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			version.put("create_time", sdf.format((Date)version.get("create_time")));
			
		}
		
		
		return version;
	}
	
	/**
	 * 仅保存数据，无审批操作
	 * @param table
	 * @param data
	 * @return
	 */
	public int saveData(String table,Map data) {
		//判断是否是更新操作
		boolean isUpdate =false;
		if(data.get("id")!=null) {
			isUpdate =true;
		}
		
		
		Date now=new Date();
		BasicLoginUser loginUser=userService.getLoginUser();
		//获取当前管理员用户的角色
		AdminLoginUser adminLoginUser=null;
		if(loginUser.getType()==1) {
			adminLoginUser=(AdminLoginUser)loginUser;
		}
		
		Map menu=null;
		if(data.get("menu_id")!=null) {
			//查询栏目及对应的审批规则
			menu=this.getJdbcDao().queryRow("select id,name,site_id,check_rule_id from "+DBTable.menu+" where id=? and del_flag=0 ", new Object[] {data.get("menu_id")});
		}
		
		
		//保存数据
		/*if(!isUpdate) {//新增操作
			int id=this.getJdbcDao().addObj(table, data);
			data.put("id", id);
		}else {//修改操作
			this.getJdbcDao().updateObj(table, data, "id");
		}*/
		//替换为统一封装的方法,便于统一处理数据
		int id=this.saveSourceData(table, data);
		if(!isUpdate) {
			data.put("id", id);
		}
		
		
		//保存数据版本信息
		Map historyRecord=new HashMap();
		historyRecord.put("data_type", table);
		
		if(data.get("menu_id")!=null) {
			historyRecord.put("menu_id", data.get("menu_id"));
		}
		
		
		historyRecord.put("check_status", 1);//设置审核状态为已通过
		
		historyRecord.put("create_time",now );
		
		
		if(loginUser!=null) {
			historyRecord.put("user_type", loginUser.getType());
			historyRecord.put("user_id", loginUser.getId());
			historyRecord.put("user_account",loginUser.getUser() );
			historyRecord.put("user_name", loginUser.getName());
		}
		
		historyRecord.put("data_id", data.get("id"));
		historyRecord.put("update_description", data.get("update_description"));
		if(table.equals(DBTable.news)) {
			historyRecord.put("title", data.get("name"));
			//去掉不保存至版本表的字段,否则审批通过后会覆盖主表的发布状态、排序、推荐等字段，造成审批前后状态不一致
			data.remove("publish");
			data.remove("recommend");
			data.remove("position");
		}else if(table.equals(DBTable.article)){
			if(menu!=null) {
				historyRecord.put("title", menu.get("name"));
			}
		}else {
			historyRecord.put("title", data.get("name"));
		}
		
		//如果标题字数过多，则进行截取
		if(historyRecord.get("title")!=null && historyRecord.get("title").toString().length()>100) {
			historyRecord.put("title", historyRecord.get("title").toString().substring(0, 100));
		}
		historyRecord.put("params", JSON.toJSONString(data));
		int historyId=this.getJdbcDao().addObj(DBTable.dataHistory, historyRecord);
		
		
		//更新版本号到数据表
		Map updateParam=new HashMap();
		updateParam.put("id", data.get("id"));
		updateParam.put("data_history_id", historyId);
		this.getJdbcDao().updateObj(table, updateParam, "id");

		return Integer.parseInt(data.get("id").toString());
		
		
	}
	
	/**
	 * 存入草稿箱，无审批操作
	 * @param table
	 * @param data
	 * @return
	 */
	public int saveDraftData(String table,Map data,String moduleName) {
		
		
		//判断是否是更新操作
		boolean isUpdate =false;
		if(data.get("id")!=null) {
			isUpdate =true;
		}
		
		
		Date now=new Date();
		BasicLoginUser loginUser=userService.getLoginUser();
		//获取当前管理员用户的角色
		AdminLoginUser adminLoginUser=null;
		if(loginUser.getType()==1) {
			adminLoginUser=(AdminLoginUser)loginUser;
		}
		
		Map menu=null;
		if(data.get("menu_id")!=null) {
			//查询栏目及对应的审批规则
			menu=this.getJdbcDao().queryRow("select id,name,site_id,check_rule_id from "+DBTable.menu+" where id=? and del_flag=0 ", new Object[] {data.get("menu_id")});
		}
		//设置审核状态为草稿
		int checkStatus=9;
		
		//保存数据
		if(!isUpdate) {//新增操作
			data.put("create_user", loginUser.getId());
			//设置审核状态
			data.put("check_status", checkStatus);
			int id=this.getJdbcDao().addObj(table, data);
			data.put("id", id);
		}else {//修改操作
			//this.getJdbcDao().updateObj(table, data, "id");
		}
		
		
		//保存数据版本信息
		Map historyRecord=new HashMap();
		historyRecord.put("data_type", table);
		historyRecord.put("module_name", moduleName);
		if(data.get("menu_id")!=null) {
			historyRecord.put("menu_id", data.get("menu_id"));
		}
		
		
		historyRecord.put("check_status", checkStatus);
		
		historyRecord.put("create_time",now );
		
		
		if(loginUser!=null) {
			historyRecord.put("user_type", loginUser.getType());
			historyRecord.put("user_id", loginUser.getId());
			historyRecord.put("user_account",loginUser.getUser() );
			historyRecord.put("user_name", loginUser.getName());
		}
		
		historyRecord.put("data_id", data.get("id"));
		historyRecord.put("update_description", data.get("update_description"));
		if(table.equals(DBTable.news)) {
			historyRecord.put("title", data.get("name"));
			
			//去掉不保存至版本表的字段,否则审批通过后会覆盖主表的发布状态、排序、推荐等字段，造成审批前后状态不一致
			data.remove("publish");
			data.remove("recommend");
			data.remove("position");
			
			
		}else if(table.equals(DBTable.appResource)){
			historyRecord.put("title", data.get("name"));
			
			//去掉不保存至版本表的字段,否则审批通过后会覆盖主表的发布状态、排序、推荐等字段，造成审批前后状态不一致
			data.remove("publish");
			data.remove("position");
		}else if(table.equals(DBTable.article)){
			/*if(menu!=null) {
				historyRecord.put("title", menu.get("name"));
			}*/
		}else {
			historyRecord.put("title", data.get("name"));
		}
		
		//如果标题字数过多，则进行截取
		if(historyRecord.get("title")!=null && historyRecord.get("title").toString().length()>100) {
			historyRecord.put("title", historyRecord.get("title").toString().substring(0, 100));
		}
		historyRecord.put("params", JSON.toJSONString(data));
		int historyId=this.getJdbcDao().addObj(DBTable.dataHistory, historyRecord);
		
		
		/*//更新版本号到数据表,草稿不需要把版本号更新到主表
		Map updateParam=new HashMap();
		updateParam.put("id", data.get("id"));
		updateParam.put("data_history_id", historyId);
		this.getJdbcDao().updateObj(table, updateParam, "id");*/

		return Integer.parseInt(data.get("id").toString());
		
		
	}
	
	public void deleteData(String table,int id) {
		//作废数据的审批记录
		this.getJdbcDao().updateSql("update "+DBTable.checkRecord+" set check_status=3 where data_type=? and data_id=? and check_status=0 ", new Object[] {table,id});
		//设置数据为删除状态
		this.getJdbcDao().updateSql("update "+table+" set del_flag=1 where id=? ", new Object[] {id});
		
		//删除素材后，标准素材文件作废
		if(table.equals(DBTable.appResource)) {
			this.getJdbcDao().updateSql("update "+DBTable.file+" set useable=0 where data_type=? and data_id=? and useable=1", new Object[] {table,id});
		}
		
	}
	
	/**
	 * 将数据更新到数据表,用于数据的统一封装
	 * @param table
	 * @param data
	 * @return id
	 */
	public int saveSourceData(String table,Map data) {
		int id=0;
		if(data==null) {
			return 0;
		}
		
		Map copyData=ObjectUtil.copy(data, Map.class);
		
		//对资讯表和素材表的正文进行过滤，去除标记data-editmark
		if((table.equals(DBTable.news)||table.equals(DBTable.appResource)) && copyData.get("content")!=null) {
			copyData.put("content", this.removeEditMark(copyData.get("content").toString()));
		}
		
		if(copyData.get("id")==null) {
			id=this.getJdbcDao().addObj(table, copyData);
		}else {
			this.getJdbcDao().updateObj(table, copyData, "id");
			id=Integer.parseInt(copyData.get("id").toString());
		}
		return id;
	}
	
	/**
	 * 保存审批数据的封装，用于发送待审批消息通知
	 * @param checkRecord
	 * @return
	 */
	public int saveCheckRecord(Map checkRecord) {
		int id=this.getJdbcDao().addObj(DBTable.checkRecord, checkRecord);
		
		//短信通知模板
		String mobileCheckNoticeTemplateCode=Config.getValue("mobileMsg.checkNoticeTemplateCode");
		//微信通知模板
		String weixinCheckNoticeTemplateCode=Config.getValue("weixin.checkNoticeTemplateId");
		
		if( (mobileCheckNoticeTemplateCode!=null && !mobileCheckNoticeTemplateCode.equals("")) || (weixinCheckNoticeTemplateCode!=null && !weixinCheckNoticeTemplateCode.equals("")) ) {
			//判断审批节点是否需要通知审批人
			Map checkRuleItem=this.getJdbcDao().queryRow("select * from "+DBTable.checkRuleItem+" where id=? and del_flag=0", new Object[] {checkRecord.get("check_rule_item_id")});
			
			
			if(checkRuleItem!=null) {
				
				//查找此角色的用户
				List userList=this.getJdbcDao().querySql("select user,name,mobile,weixin_appid,weixin_openid from "+DBTable.user+" where role like ? and publish=1 and del_flag=0 order by id asc limit 0,100", new Object[] {"%,"+checkRuleItem.get("role_id").toString()+",%"});
				if(userList!=null) {
					if(checkRuleItem.get("open_mobile_notice").toString().equals("1") && mobileCheckNoticeTemplateCode!=null && !mobileCheckNoticeTemplateCode.equals("")) {
						for(int i=0;i<userList.size();i++) {
							Map user=(Map)userList.get(i);
							if(user.get("mobile")!=null && !user.get("mobile").toString().equals("")) {
								//发送通知短信
								Map msgParam=new HashMap();
								if(user.get("name")!=null && !user.get("name").toString().equals("")) {
									msgParam.put("name", user.get("name").toString());
								}else {
									msgParam.put("name", user.get("user").toString());
								}
								msgParam.put("title", checkRecord.get("data_title").toString());
								mobileMsgService.send(user.get("mobile").toString(), mobileCheckNoticeTemplateCode, msgParam);
							}
						}
					}
					
					if(checkRuleItem.get("open_weixin_notice").toString().equals("1") && weixinCheckNoticeTemplateCode!=null && !weixinCheckNoticeTemplateCode.equals("")) {
						String appid=Config.getValue("weixin.appId");
						String secret=Config.getValue("weixin.appSecret");
						
						if(StringUtil.isNotNullOrEmpty(appid) && StringUtil.isNotNullOrEmpty(secret)) {
							Map msgParams=new HashMap();
							msgParams.put("first", "您有新的审批需要处理");
							//发起者
							msgParams.put("keyword1", checkRecord.get("submit_user_name").toString());
							//单据类型
							Map typeItem=this.dictionaryService.getDictionaryItem("moduleTypeVars", checkRecord.get("data_type").toString());
							msgParams.put("keyword2",typeItem.get("text").toString() );
							//审核内容
							msgParams.put("keyword3", checkRecord.get("data_title").toString());
							//发起时间
							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							msgParams.put("keyword4", sdf.format((Date)checkRecord.get("submit_time")));
							
							msgParams.put("remark", "请点击查看");
							String link=null;
							try {
								String webUrl="/#/checkRecord";
								String action="/adminWeixin/login?action="+java.net.URLEncoder.encode(webUrl,"UTF-8");
								link = Config.getValue("app.adminapiDomain")+"/adminWeixin/getBaseCode?action="+ java.net.URLEncoder.encode(action,"UTF-8");
							} catch (UnsupportedEncodingException e) {
								log.error(e.getMessage(),e);
							}
							
							for(int i=0;i<userList.size();i++) {
								Map user=(Map)userList.get(i);
								
								if(StringUtil.isNotNullOrEmpty(user.get("weixin_appid")) && StringUtil.isNotNullOrEmpty(user.get("weixin_openid")) && user.get("weixin_appid").toString().equals(appid)) {
									//发送微信模板消息通知
									weixinApiService.sendTemplateMessage(appid, secret, weixinCheckNoticeTemplateCode, msgParams, link, user.get("weixin_openid").toString());
								}
								
								
							}
						}
						
						
						
					}
				}
			}
		}
		
		
		
		return id;	
	}
	
	public void checkResultNotice(Map checkRecord,boolean result) {
		//int id=this.getJdbcDao().addObj(DBTable.checkRecord, checkRecord);
		//判断审批节点是否需要通知审批人
		Map checkRule=this.getJdbcDao().queryRow("select * from "+DBTable.checkRule+" where id=? and del_flag=0", new Object[] {checkRecord.get("check_rule_id")});
		
		
		if(checkRule!=null) {
			Map user=this.getJdbcDao().queryRow("select user,name,mobile,weixin_appid,weixin_openid from "+DBTable.user+" where id=? and publish=1 and del_flag=0 ", new Object[] {checkRecord.get("submit_user_id")});
			if(result) {//审批通过结果通知
				//审核通过短信通知模板
				String mobileCheckOKTemplateCode=Config.getValue("mobileMsg.checkResultOkTemplateCode");
				
				if(checkRule.get("open_mobile_notice").toString().equals("1") && mobileCheckOKTemplateCode!=null && !mobileCheckOKTemplateCode.equals("")) {
					
					
					if(user.get("mobile")!=null && !user.get("mobile").toString().equals("")) {
						//发送通知短信
						Map msgParam=new HashMap();
						if(user.get("name")!=null && !user.get("name").toString().equals("")) {
							msgParam.put("name", user.get("name").toString());
						}else {
							msgParam.put("name", user.get("user").toString());
						}
						msgParam.put("title", checkRecord.get("data_title").toString());
						
						if(checkRecord.get("data_type").toString().equals(DBTable.news)) {
							msgParam.put("type", "文章");
						}else if(checkRecord.get("data_type").toString().equals(DBTable.appResource)) {
							msgParam.put("type", "素材");
						}
						mobileMsgService.send(user.get("mobile").toString(), mobileCheckOKTemplateCode, msgParam);
					}
					
				}
				
				
				
				//微信通知模板
				String weixinCheckResultTemplateCode=Config.getValue("weixin.checkResultTemplateId");
				if(checkRule.get("open_weixin_notice").toString().equals("1") && weixinCheckResultTemplateCode!=null && !weixinCheckResultTemplateCode.equals("")) {
					
					
					String appid=Config.getValue("weixin.appId");
					String secret=Config.getValue("weixin.appSecret");
					
					if(StringUtil.isNotNullOrEmpty(appid) && StringUtil.isNotNullOrEmpty(secret)) {
						
						
						if(StringUtil.isNotNullOrEmpty(user.get("weixin_appid")) && StringUtil.isNotNullOrEmpty(user.get("weixin_openid")) && user.get("weixin_appid").toString().equals(appid)) {
							
							Map msgParams=new HashMap();
							msgParams.put("first", "审批结果通知");
							
							//发布类型
							Map typeItem=this.dictionaryService.getDictionaryItem("moduleTypeVars", checkRecord.get("data_type").toString());
							msgParams.put("keyword1",typeItem.get("text").toString() );
							//发布标题
							msgParams.put("keyword2", checkRecord.get("data_title").toString());
							//发布时间
							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							msgParams.put("keyword3", sdf.format((Date)checkRecord.get("submit_time")));
							//审核结果，字典变量可能存在已批注类型，所以不采用字典变量
							//Map resultItem=this.dictionaryService.getDictionaryItem("checkStatusVars", checkRecord.get("check_status").toString());
							//msgParams.put("keyword4", resultItem.get("text").toString());
							msgParams.put("keyword4", "审核通过");
							msgParams.put("remark", "请登录系统进行后续操作");
							String link=null;
							
							//发送微信模板消息通知
							weixinApiService.sendTemplateMessage(appid, secret, weixinCheckResultTemplateCode, msgParams, link, user.get("weixin_openid").toString());
						}
						
					}
					
				}
				
				
			}else {//审批未通过结果通知
				//审核失败短信通知模板
				String mobileCheckFailTemplateCode=Config.getValue("mobileMsg.checkResultFailTemplateCode");
				
				if(checkRule.get("open_mobile_notice").toString().equals("1") && mobileCheckFailTemplateCode!=null && !mobileCheckFailTemplateCode.equals("")) {
					
					if(user.get("mobile")!=null && !user.get("mobile").toString().equals("")) {
						//发送通知短信
						Map msgParam=new HashMap();
						if(user.get("name")!=null && !user.get("name").toString().equals("")) {
							msgParam.put("name", user.get("name").toString());
						}else {
							msgParam.put("name", user.get("user").toString());
						}
						msgParam.put("title", checkRecord.get("data_title").toString());
						mobileMsgService.send(user.get("mobile").toString(), mobileCheckFailTemplateCode, msgParam);
					}
					
				}
				
				
				//微信通知模板
				String weixinCheckResultTemplateCode=Config.getValue("weixin.checkResultTemplateId");
				if(checkRule.get("open_weixin_notice").toString().equals("1") && weixinCheckResultTemplateCode!=null && !weixinCheckResultTemplateCode.equals("")) {
					
					
					String appid=Config.getValue("weixin.appId");
					String secret=Config.getValue("weixin.appSecret");
					
					if(StringUtil.isNotNullOrEmpty(appid) && StringUtil.isNotNullOrEmpty(secret)) {
						
						
						if(StringUtil.isNotNullOrEmpty(user.get("weixin_appid")) && StringUtil.isNotNullOrEmpty(user.get("weixin_openid")) && user.get("weixin_appid").toString().equals(appid)) {
							
							Map msgParams=new HashMap();
							msgParams.put("first", "审批结果通知");
							
							//发布类型
							Map typeItem=this.dictionaryService.getDictionaryItem("moduleTypeVars", checkRecord.get("data_type").toString());
							msgParams.put("keyword1",typeItem.get("text").toString() );
							//发布标题
							msgParams.put("keyword2", checkRecord.get("data_title").toString());
							//发布时间
							SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
							msgParams.put("keyword3", sdf.format((Date)checkRecord.get("submit_time")));
							//审核结果，字典变量可能存在已批注类型，所以不采用字典变量
							//Map resultItem=this.dictionaryService.getDictionaryItem("checkStatusVars", checkRecord.get("check_status").toString());
							//msgParams.put("keyword4", resultItem.get("text").toString());
							msgParams.put("keyword4", "未通过");
							msgParams.put("remark", "请登录系统进行后续操作");
							String link=null;
							
							//发送微信模板消息通知
							weixinApiService.sendTemplateMessage(appid, secret, weixinCheckResultTemplateCode, msgParams, link, user.get("weixin_openid").toString());
						}
						
					}
					
				}
				
			}
		}
			
	}
	
	public List getNextCheckRuleItems(int checkRuleId,Map checkRuleItem) {
		List checkRuleItems=new ArrayList();
		
		int position=0;
		
		List whereParamList=new ArrayList();
		String where=" where check_rule_id=? and publish=1 and del_flag=0 ";
		whereParamList.add(checkRuleId);
		if(checkRuleItem!=null) {
			//如果当前是并行节点，则需要从下一个非并行节点开始查找
			Map tmpCheckRuleItem=this.getJdbcDao().queryRow("select * from "+DBTable.checkRuleItem+" where check_rule_id=? and position>? and id!=? and publish=1 and del_flag=0 limit 0,1", new Object[] {checkRuleItem.get("check_rule_id"),checkRuleItem.get("position"),checkRuleItem.get("id")});
			while(tmpCheckRuleItem!=null && tmpCheckRuleItem.get("asyn").toString().equals("1")) {
				checkRuleItem=tmpCheckRuleItem;
				tmpCheckRuleItem=this.getJdbcDao().queryRow("select * from "+DBTable.checkRuleItem+" where check_rule_id=? and position>? and id!=? and publish=1 and del_flag=0 limit 0,1", new Object[] {checkRuleItem.get("check_rule_id"),checkRuleItem.get("position"),checkRuleItem.get("id")});
			}
			where+=" and id!=? and position>? ";
			whereParamList.add(checkRuleItem.get("id"));
			whereParamList.add(checkRuleItem.get("position"));
		}
		
		
		List checkRuleItemList=this.getJdbcDao().querySql("select * from "+DBTable.checkRuleItem+where+" order by position asc limit 0,100", whereParamList.toArray());
		
		if(checkRuleItemList!=null && checkRuleItemList.size()>0) {
			
			for(int i=0;i<checkRuleItemList.size();i++) {
				Map tmpCheckRuleItem=(Map)checkRuleItemList.get(i);
				
				//log.info("选择审批节点"+JSON.toJSONString(tmpCheckRuleItem));
				
				//如果是并行节点，允许存入多个
				int asyn=Integer.parseInt(tmpCheckRuleItem.get("asyn").toString());
				if(asyn==1) {
					checkRuleItems.add(tmpCheckRuleItem);
				}else{
					if(checkRuleItems.size()==0) {
						checkRuleItems.add(tmpCheckRuleItem);	
					}
					break;
				}
				//checkRuleItem=tmpCheckRuleItem;
			}	
		}
		return checkRuleItems;
	}
	
	public String removeEditMark(String htmlContent) {
		
		
		Document doc = Jsoup.parse(htmlContent);
		Elements elements=doc.getElementsByAttribute("data-editmark");
		if(elements!=null && elements.size()>0) {
			Iterator<Element> iterator=elements.listIterator();
			while(iterator.hasNext()){
				Element element = iterator.next();
				//log.info(element.html());
				Element element2=new Element("font");
				element2.html(element.html());
				element.replaceWith(element2);
			}
			return doc.html();
		}
		return htmlContent;
	}

}
